﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using JelleDruyts.Windows;
using Schedulr.Messages;
using Schedulr.Models;
using Schedulr.ViewModels;

namespace Schedulr.Infrastructure
{
    public class BatchIdGroupDescription : GroupDescription
    {
        private Account account;
        private IList<Picture> pictures;
        private IList<DateTime> nextRunTimes;

        public BatchIdGroupDescription(Account account, IList<Picture> pictureList)
        {
            this.account = account;
            this.pictures = pictureList;
            Messenger.Register<UploadScheduleChangedMessage>(OnUploadScheduleChanged);
            Messenger.Register<PictureQueueChangedMessage>(OnPictureQueueChanged);
        }

        private void OnPictureQueueChanged(PictureQueueChangedMessage message)
        {
            RefreshGroupNames();
        }

        private void OnUploadScheduleChanged(UploadScheduleChangedMessage message)
        {
            RefreshGroupNames();
        }

        private void RefreshGroupNames()
        {
            this.nextRunTimes = null;
            this.OnPropertyChanged(new PropertyChangedEventArgs("GroupNames"));
        }

        public override object GroupNameFromItem(object item, int level, CultureInfo culture)
        {
            var picture = ((PictureViewModel)item).Picture;
            var name = GetName(picture.BatchId);
            return new BatchHeader(picture.BatchId, name);
        }

        private string GetName(int batchId)
        {
            // If no proper batch name could be constructed, just return a generic batch number.
            var name = "Batch " + batchId;
            if (this.pictures != null)
            {
                var picturesInBatch = this.pictures.Where(p => p.BatchId == batchId).ToList();
                if (picturesInBatch.Count > 0)
                {
                    if (picturesInBatch.All(p => p.DateUploaded.HasValue))
                    {
                        // These pictures have already been uploaded, name the batch according to the uploaded date.
                        // Assume that they have all been uploaded at the same time.
                        var uploaded = picturesInBatch.First().DateUploaded.Value;
                        name = "Uploaded on " + uploaded.ToString("f");
                    }
                    else
                    {
                        if (this.nextRunTimes == null)
                        {
                            var numberOfBatches = this.pictures.GroupBy(p => p.BatchId).Select(p => p.First()).Count();
                            this.nextRunTimes = ScheduledTaskClient.GetNextRunTimesForAccount(this.account, numberOfBatches);
                        }
                        if (this.nextRunTimes != null && this.nextRunTimes.Count >= batchId)
                        {
                            name += string.Format(CultureInfo.CurrentCulture, " - Scheduled for {0}", this.nextRunTimes[batchId - 1].ToString("f"));
                        }
                    }
                }
                name += picturesInBatch.Count.ToCountString("picture", " (", ")");
            }

            return name;
        }
    }
}